#include "dkglTexture.h"
#include "dkglUtility.h"

// use DevIL as image file helper
#include <IL/il.h>



namespace DKGL
{

Texture::Texture()
{
	m_nWidth = m_nHeight = 0;
	m_pBuffer = NULL;
	m_nChannel = 0;
}

Texture::~Texture()
{
	glDeleteTextures(1, &mTexID);
	delete [] m_pBuffer;
}

void Texture::bind()
{
    glBindTexture(GL_TEXTURE_2D, mTexID);
}

bool Texture::load(const String& path)
{
    //1. try to bind an image in DevIL
    ILuint ImgId = 0;
    ilGenImages(1, &ImgId);
    ilBindImage(ImgId);

    //2. Load Image from file
    ILboolean ilresult = ilLoadImage(path.c_str());

    if (!ilresult)
    {
        ILenum Error;
        Error = ilGetError();

        //std::string(iluErrorString()

        return false;
    }

    //3. query the dimension
    m_nWidth = ilGetInteger(IL_IMAGE_WIDTH);
    m_nHeight = ilGetInteger(IL_IMAGE_HEIGHT);

    //4. Enable GLTexture and Bind
    glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &mTexID);
	glBindTexture(GL_TEXTURE_2D, mTexID);

    //5. Setup Texture param
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	
    //6. Upload bitstream to OpenGL context
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_nWidth, m_nHeight, 0, GL_RGB, 
		GL_UNSIGNED_BYTE, ilGetData());

    //7. Free IL image memory
    ilBindImage(0);
    ilDeleteImage(ImgId);

    return true;
}

#if 0

bool Texture::load(const std::string& path)
{
#ifdef DKGL_USE_GDI_PLUS
	Gdiplus::Color color;
	Gdiplus::Bitmap bitmap(s2ws(path).c_str());
	GLubyte *buf = NULL;
	INT i, j, y, width, height;

	Gdiplus::Status result = bitmap.GetLastStatus();
	if(result!=Gdiplus::Ok)
		return false;

	width = bitmap.GetWidth();
	height = bitmap.GetHeight();

	buf = new GLubyte[width*height*3];

	for(j=0;j<height;j++)
	{	
		for(i=0;i<width;i++)
		{
			y = (height - 1) - j;
			bitmap.GetPixel(i,y,&color);
			buf[3*(j*width + i) + 0] = static_cast<GLubyte>(color.GetR());
			buf[3*(j*width + i) + 1] = static_cast<GLubyte>(color.GetG());
			buf[3*(j*width + i) + 2] = static_cast<GLubyte>(color.GetB()); 
		}	
	}

	glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &mTexID);
	
	glBindTexture(GL_TEXTURE_2D, mTexID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, 
		GL_UNSIGNED_BYTE, buf);
	delete [] buf;
	return true;
#else
	unsigned int buf_len, i;
	CImg<unsigned char> image(path.c_str());
	
	//image.assign(path.c_str());
	int j;

	//image.permute_axes("zyxv"); 
	j = image.dimx();
	m_nWidth = image.dimx();
	m_nHeight = image.dimy();
	//m_nChannel = image.dimz();
	m_nChannel = image.dimv();

	buf_len = m_nWidth*m_nHeight*m_nChannel;

	delete [] m_pBuffer;

	//m_pBuffer = new unsigned char[buf_len];

	//for(i=0;i<buf_len;i++)
	//	m_pBuffer[i] = image.data[i];

	glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &mTexID);
	//i = mTexID;
	glBindTexture(GL_TEXTURE_2D, mTexID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, 
		GL_UNSIGNED_BYTE, image.ptr());
	
	return true;
#endif
}

#endif

void Texture::freeBuffer()
{
	delete [] m_pBuffer;
	m_pBuffer = NULL;
}

}